﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Reflection.Emit;
using Kawanon.Usability;
using QTPlugin.Interop;
using System.Runtime.InteropServices;
using System.Security;
using Kawanon.QtHoney;
using Kawanon.Usability.Visualization;
using System.IO;
using System.IO.Compression;
using Microsoft.Win32;
using Kawanon.Sessions;
using System.Diagnostics;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting;
using Kawanon.Foundation;
using System.Globalization;
using Kawanon.Localization;

namespace TestUnit
{
	[ComImport, SuppressUnmanagedCodeSecurity, Guid("6d5140c1-7436-11ce-8034-00aa006009fa"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface _IServiceProvider
	{
		void QueryService(ref Guid guid, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object Obj);
	}

	public partial class Form1 : Form
	{
		FolderViewWorkspace m_listview;

		public Form1()
		{
			InitializeComponent();

			string s = StringResource.Localize("HOGE");
			s = StringResource.Localize("HOGE", "hoge");
			s = StringResource.Localize("HOGE", true);
			s = StringResource.Localize("Caption_Resource", 0);
			s = StringResource.Localize("Caption_Resource", 5);
			s = StringResource.Localize("Caption_Resource", 5, true);
			s = StringResource.Localize(Caption.Error);
			s.ToCharArray();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			//Kawanon.QtHoney.MainPlugin.Uninstall();

			Plugins.SettingsChanged += new EventHandler(Plugins_SettingsChanged);

			Kawanon.QtHoney.MainPlugin main = new Kawanon.QtHoney.MainPlugin();
			try
			{
				//main.Open(null, null);
				main.Initialize(new int[] { 2,0,1 });
			}
			catch (Exception)
			{
			}

			string name = main.GetName(2);

			webBrowser1.Navigate(Application.StartupPath);

			//Form form = new Kawanon.QtHoney.GestureForm();
			//form.Show(this);

			//Kawanon.QtHoney.DebugForm f2 = new Kawanon.QtHoney.DebugForm();
			//f2.PropertyGrid.SelectedObject = f2;
			//f2.Show();

			//----
			//object o = Kawanon.QtHoney.DynamicReflectorFactory.Create(f2);
			//f2.PropertyGrid.SelectedObject = o;

			//Kawanon.QtHoney.MainPlugin plugin = new Kawanon.QtHoney.MainPlugin();
			//plugin.GetImage(true, 0);

			//Kawanon.QtHoney.PluginCustomItem item = new Kawanon.QtHoney.PluginItems.MergeWindowsButton();
			//Image image = item.GetImage(true);

			//image.ToString();


			//object[] src = new object[] { "123", 12, typeof(Object) };
			//var form = new Kawanon.QtHoney.ChooseFromArrayForm();
			//form.Source = src;
			//DialogResult res = form.ShowDialog();

			//form.ToString();

			//GestureExpression expr = new GestureExpression("URDL", new Kawanon.Usability.Actions.Pending());
			//bool b = expr.TrailsEquals(new int[] { 0, 1, 2, 3 });
			//bool b2 = expr.TrailsEquals(new int[] { 1, 2 });
			//b2.ToString();

			//int index = 0;
			//for (; index < main.Count; index++)
			//{
			//    if (main.GetName(index) == "セッションマネージャ")
			//    {
			//        break;
			//    }
			//}
			//ToolStripItem stripItem = main.CreateItem(true, QTPlugin.DisplayStyle.NoLabel, index);
			//stripItem.Owner = new ToolStrip();

			//stripItem.PerformClick();

			List<Session> list = new List<Session>(new SessionManager().Load());
			list.ToArray();

			//Stream stm = Plugins.LoadLanguageFile();
			//stm.ToString();

			string[] names = Enum.GetNames(typeof(HogeEnum));
			Array values = Enum.GetValues(typeof(HogeEnum));
			names.ToString();
			values.ToString();
		}

		public enum HogeEnum
		{
			A = 10,
			B = 1,
			C,
			D = 10,
			E,
		};

		void Plugins_SettingsChanged(object sender, EventArgs e)
		{
			if (m_listview != null)
			{
				m_listview.Dispose();
				m_listview = null;
			}

			timer1.Start();
		}

		private void ToolStripMenuItem_GestureForm_Click(object sender, EventArgs e)
		{
			//Kawanon.QtHoney.GestureForm form = new Kawanon.QtHoney.GestureForm(null);
			//form.ShowDialog(this);

		}

		public static void Dump(string val)
		{
			Stream ms = Persistence.CreateValueStream(val);
			if (ms == null)
			{
				return;
			}

			ms.Seek(0, SeekOrigin.Begin);
			DeflateStream inflate = new DeflateStream(ms, CompressionMode.Decompress);
			string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);
			Stream os = new FileStream(Path.Combine(dir, val +".bin"), FileMode.Create);
			int c;
			while ((c = inflate.ReadByte()) != -1)
			{
				os.WriteByte((byte)c);
			}

			os.Close();
		}

		private void Form1_FormClosing(object sender, FormClosingEventArgs e)
		{
			//List<GestureExpression> list = new List<GestureExpression>();
			//GestureSettings.LoadExpressions(list);
			//GestureSettings.DumpExpressions(list);

			Dump("Expressions");
			Dump("Rendering");
			Dump("Sessions");
			Dump("Gesture");
		}

		private void Form1_Activated(object sender, EventArgs e)
		{
			ToolTip tooltip = new ToolTip();
			//tooltip.AutoPopDelay = 32767;
			//		tooltip.IsBalloon = true;
			//tooltip.Active = true;
			//	tooltip.UseFading = true;
			//tooltip.ShowAlways = true;
			//	tooltip.ToolTipTitle = "hoge!";
			//Dbg.Play();
			//tooltip.SetToolTip(listView1, "hoge");
			//tooltip.Show("hoge", Control.FromHandle(this.Handle), 0, 0, 20 * 1000);

		}

		private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
		{
			//NOTE: この時点ではアクティブなShellViewは変化していない (Internet Explorer_Server)

			timer1.Start();
		}

		class BrowserProxy : RealProxy
		{
			public BrowserProxy(Type t)
				: base(t)
			{
			}

			public override IMessage Invoke(IMessage msg)
			{
				IMethodCallMessage req = msg as IMethodCallMessage;

				// RemotingServices.ExecuteMessageは呼ばず、メソッドは実行しない。
				
				return null;
			}
		}

		private void timer1_Tick(object sender, EventArgs e)
		{
			Guid IID_IShellBrowser = new Guid("{000214E2-0000-0000-C000-000000000046}");

			_IServiceProvider provider = webBrowser1.ActiveXInstance as _IServiceProvider;

			timer1.Stop();

			object obj1;
			provider.QueryService(ref IID_IShellBrowser, ref IID_IShellBrowser, out obj1);
			IShellBrowser browser = (IShellBrowser)obj1;

			IShellView view;
			browser.QueryActiveShellView(out view);
			IntPtr hwndView;
			view.GetWindow(out hwndView);
			IntPtr listview = Utility.FindChildWindow(hwndView, Utility.EqualsClassName("SysListView32"));


			var nw = new Kawanon.QtHoney.FolderViewWorkspace();
			nw.Handle = listview;
			nw.Adapter = new SubclassedAdapter(listview);
			nw.View = new ListViewProxy(listview);
			nw.StatusBarHandle = statusBar1.Handle;
			nw.ShellView = view;
			nw.DrawTrails = true;
			nw.Renderer = TrailRendererFactory.CreateInstance(Persistence.GetInformation<RenderingInformation>());

			GestureProvider gprovider = new GestureProvider();
			gprovider.Expressions = GestureSettings.LoadAvailableExpressions();
			gprovider.GestureInformation = Persistence.GetInformation<GestureInformation>();
			nw.Provider = gprovider;

			m_listview = nw;


			//----

			//BrowserProxy proxy = new BrowserProxy(typeof(IShellBrowser));
			//IShellBrowser browser2 = proxy.GetTransparentProxy() as IShellBrowser;

			//browser2.BrowseObject(IntPtr.Zero, 1234);

			/*
			try
			{
				Kawanon.Foundation.WindowHook hk = Kawanon.Foundation.WindowHook.FromKind(HookKind.WH_CBT);
				hk.Captured += new WindowHook.Handler(delegate(int code, IntPtr wParam, IntPtr lParam)
				{
					" ".ToCharArray();
				});
			}
			catch (NullReferenceException)
			{
			}
			GC.Collect();
			GC.WaitForPendingFinalizers();
			GC.WaitForFullGCComplete();
			*/
		}

		private void menuItem2_Click(object sender, EventArgs e)
		{
			RenderingInformation info = Persistence.GetInformation<RenderingInformation>();
			PropertiesForm form = new PropertiesForm();
			form.PropertyGrid.SelectedObject = info;
			form.ShowDialog(this);

			Persistence.SaveInformation(info);
		}

		private void menuItem3_Click(object sender, EventArgs e)
		{
			OptionsForm form = new OptionsForm(null);
			form.ShowDialog(this);
		}

		private void timer2_Tick(object sender, EventArgs e)
		{
			int count = Environment.ProcessorCount;
			statusBarPanel1.Text = count.ToString();
			//Process proc = Process.GetCurrentProcess();
			//TimeSpan span = DateTime.Now - proc.StartTime;
			//statusBarPanel2.Text = (proc.TotalProcessorTime.TotalSeconds / span.TotalSeconds).ToString();
			//int score =  * 10 + ;

			Stopwatch sw = new Stopwatch();
			Bitmap bmp = new Bitmap(8, 1);
			sw.Start();
			for (int i = 0; i < bmp.Width; i++)
			{
				bmp.SetPixel(i, 0, Color.FromArgb(((i << 24) | (i << 16) | (i << 8)) ^ -1));
			}
			sw.Stop();
			bmp.Dispose();

			TimeSpan span = sw.Elapsed;
			statusBarPanel2.Text = span.TotalMilliseconds.ToString();

			statusBarPanel3.Text = (count - span.TotalMilliseconds * 100).ToString();
		}

		private void menuItem4_Click(object sender, EventArgs e)
		{
			Kawanon.QtHoney.Utility.EditInformation<Kawanon.Usability.GestureInformation>(this, "hoge", null);
		}

		private void menuItem5_Click(object sender, EventArgs e)
		{
			OptionsForm form = new OptionsForm(null);
			form.StartPosition = FormStartPosition.CenterScreen;
			form.Owner = Form.ActiveForm;
			form.Visible = true;
		}

		public class TestController
		{
			internal event MessageEventHandler MessageCaptured;

			internal delegate bool MessageEventHandler(ref Message msg);

			private bool Hoge { get; set; }

			private void None()
			{
				MessageCaptured += new MessageEventHandler((ref Message m) => { return false; });
			}
		}

		[Serializable]
		private class HogeAction1 : Kawanon.Usability.Action
		{
			public override void Execute(Action.Arguments args)
			{
				throw new NotImplementedException();
			}
		}

		private void menuItem1_Click(object sender, EventArgs e)
		{
			object controller = new TestController();
			Kawanon.Foundation.NativeWindowControllerAdapter adapter = 
				new Kawanon.Foundation.NativeWindowControllerAdapter(controller);

			adapter.Dispose();

			Reflection.SetProperty(controller, "Hoge", true);

			object o = Reflection.GetProperty(controller, "Hoge");
			o.ToString();


			int index = Convert.ToInt32(QTPlugin.Commands.BrowseFolder);
			index.ToString();

			var list = GestureSettings.LoadAllExpressions();
			list.Add(new GestureExpression("URDLURDL", new HogeAction1()));
			GestureSettings.SaveExpressions(list);

			// これに対応するのは難しい..
			/*
			var config = Persistence.LoadInformation<GestureInformation>();
			RockerExpression rocker = new RockerExpression();
			rocker.Action = new HogeAction1();
			config.RockerExpressions.Add(rocker);
			Persistence.SaveInformation(config);
			*/
		}

		private void menuItem6_Click(object sender, EventArgs e)
		{
			// メモリリークテスト
			this.UseWaitCursor = true;

			for (int i = 0; i < 1000; i++)
			{
				var render = Kawanon.Usability.Visualization.TrailRendererFactory.CreateInstance(
					Persistence.GetInformation<RenderingInformation>());
				render.WindowHandle = this.Handle;

				render.SetOrigin(new Point());
				render.DrawLine(new Point(), new Point(100, 100));

				System.Threading.Thread.Sleep(300);
				Application.DoEvents();

				IDisposable d = render as IDisposable;
				//d.Dispose();
				//render.Erase();
			}

			this.UseWaitCursor = false;
		}

		private void menuItem7_Click(object sender, EventArgs e)
		{
			ContextMenuStrip strip = new ContextMenuStrip();

			var factory = new Kawanon.Usability.PopupMenuFactory();
			factory.Workspace = m_listview;
			factory.CreateItems(strip.Items, PopupMenus.Application);

			strip.Show(Cursor.Position);
		}
	}
}
